home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / tri.arc / TRI.ASM
Assembly Source File  |  1986-03-15  |  6KB  |  143 lines

  1. Title: TRI - 8088 routine CALLed from BASIC   Steve Muenter
  2.  
  3. comment *This routine produces polyphonic music with three
  4.    voices.  The frequencies and durations of the notes
  5.    are passed to this routine in an integer array.
  6.  
  7.    Called from BASIC via:
  8.  
  9.         CALL TRI(TUNE%(0))
  10.  
  11.    Where:
  12.  
  13.         TUNE% is an integer array
  14.  
  15.    TUNE% is treated by TRI as data words with the three most
  16.    significant bits identifying the type of data.    000 causes
  17.    the routine to terminate and return to BASIC.  001 sets
  18.    the duration of play of the voices before being updated.
  19.    010 sets the tempo of the playback.  011 is unused.  100
  20.    sets the period for voice 1 which is slightly louder than
  21.    the rest.  101 sets the period for voice 2.  110 sets the
  22.    period for voice 3.
  23.    *
  24.  
  25. cseg    segment
  26.         assume CS:cseg, DS:cseg, ES:nothing
  27. ;       db      0FDH            ;indicates BLOAD file
  28. ;       dw      0               ;segment--BASIC will use default
  29. ;       dw      0               ;offset--specify in BLOAD command
  30. ;       dw      rtn_len         ;length of the routine
  31.  
  32. spkr_io equ     61H
  33.  
  34. tri     proc    far
  35.         push    bp
  36.         mov     bp,sp
  37.         mov     ax,(bp+6)       ;get address of TUNE%(0) off stack
  38.         sub     ax,2            ;required for first time in sort
  39.         push    ax              ;save on stack
  40.         mov     ax,1FFFH        ;default tempo data
  41.         push    ax              ;save on stack
  42.         push    ax              ;initialize tempo counter
  43.         xor     ax,ax           ;must write 0 into voice count and
  44.         mov     bx,ax           ; data registers
  45.         mov     dx,ax
  46.         mov     si,ax
  47.         mov     bp,ax
  48.         mov     di,ax
  49.         mov     es,ax
  50. ;
  51. ;This section sorts the tune data into the appropriate registers
  52. ;Voice period data is stored in ES for voice 1, DI for voice 2,
  53. ;and SI for voice 3.  The voice period count is stored in BX for
  54. ;voice 1, DX for voice 2, and BP for voice 3.
  55. ;
  56. sort:   push    bx
  57.         push    dx
  58.         push    bp
  59.  
  60. sort_1: mov     bp,sp
  61.         mov     bx,(bp+10)      ;get tune pointer
  62.         add     bx,2            ;point to next tune data
  63.         mov     (bp+10),bx      ;restore updated tune pointer
  64.         mov     ax,(bx)         ;get tune data in AX
  65.         mov     dx,ax           ;make a copy in DX
  66.         and     dx,1FFFH        ;strip off 3 data type bits
  67.         shl     ax,1            ;move msb into carry bit
  68.         jnc     sort_4          ;jump if end, duration, or tempo data
  69.         shl     ax,1            ;move 2nd msb into carry bit
  70.         jc      sort_3          ;jump if voice 3 data
  71.         shl     ax,1            ;move 3rd msb into carry bit
  72.         jc      sort_2          ;jump if voice 2 data
  73.         mov     es,dx           ;store voice 1 data in ES
  74.         jmp     sort_1
  75. sort_2: mov     di,dx           ;store voice 2 data in DI
  76.         jmp     sort_1
  77. sort_3: mov     si,dx           ;store voice 3 data in SI
  78.         jmp     sort_1          ;ignore
  79. sort_4: shl     ax,1            ;move 2nd msb into carry bit
  80.         jnc     sort_6          ;jump if end or duration bit
  81.         jnc     sort_6          ;jump if end or duration data
  82.         shl     ax,1
  83.         jnc     sort_5          ;jump if tempo data
  84.         jmp     sort_1          ;ignore
  85. sort_5: mov     (bp+8),dx       ;store tempo
  86.         mov     (bp+6),dx       ;initialize tempo counter
  87.         jmp     sort_1
  88. sort_6: shl     ax,1            ;move 3rd msb into carry
  89.         jc      sort_7          ;jump if duration
  90.         jmp     end
  91. sort_7: mov     cx,dx           ;store duration data
  92.         pop     bp
  93.         pop     dx
  94.         pop     bx
  95.         cli                     ;turn off interrupts during play
  96. loop:   pop     ax              ;get current tempo count
  97.         dec     ax              ;subtract 1
  98.         push    ax              ;restore tempo count
  99.         jnz     play            ;jump if some tempo remains
  100.         pop     ax              ;reset tempo counter
  101.         pop     ax
  102.         push    ax
  103.         push    ax
  104.         loop    play            ;decrement duration counter
  105.         sti                     ;turn ints back on during sort
  106.         jmp     sort            ;get new tune data if duration up
  107. ;
  108. ;This routine plays the notes until the duration counter in CX
  109. ;reaches zero.    At that time, the new data is sorted.
  110. ;
  111. play:   add     bx,si           ;add voice 3 data to count
  112.         rol     bx,1            ;get msb of voice 3 count
  113.         mov     al,12H          ;keeps keyboard clk on and
  114.         rcl     al,1            ; casette motor relay off
  115.         rcl     al,1
  116.         out     spkr_io,al      ;output voice 3 state to speaker
  117.         ror     bx,1            ;restore bx to original state
  118.         add     dx,di           ;add voice 2 data to count
  119.         rol     dx,1
  120.         mov     al,12H
  121.         rcl     al,1
  122.         rcl     al,1
  123.         out     spkr_io,al
  124.         ror     dx,1
  125.         mov     ax,es
  126.         add     bp,ax           ;add voice 1 data to count
  127.         rol     bp,1
  128.         mov     al,12H
  129.         rcl     al,1
  130.         rcl     al,1
  131.         out     spkr_io,al
  132.         ror     bp,1
  133.         jmp     loop
  134. end:    add     sp,12
  135.         pop     bp
  136.         mov     ax,cs
  137.         mov     es,ax
  138.         ret     2
  139. tri     endp
  140. rtn_len equ     $-tri           ;length of routine for header
  141. cseg    ends
  142.         end     tri
  143.